package b_DFS_DFSApplication;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;

public class Path {

    private Graph G;
    private int s, t;

    private int[] pre;
    private boolean[] visited;

    public Path(Graph G, int s, int t){

        G.validateVertex(s);
        G.validateVertex(t);

        this.G = G;
        this.s = s;
        this.t = t;

        visited = new boolean[G.V()];
        pre = new int[G.V()];
        for(int i = 0; i < pre.length; i ++)
            pre[i] = -1;

        dfs(s, s);
        for(boolean e: visited)
            System.out.print(e + " ");
        System.out.println();
    }

    private boolean dfs(int v, int parent){ //先理解过程理清思路，再设计函数（包括返回值是否为void），然后再明确一遍语意去写代码，写完结合微观递归进行查漏补缺；

        visited[v] = true;
        pre[v] = parent;

        if(v == t) return true;

        for(int w: G.adj(v))
            if(!visited[w])
                if(dfs(w, v))
                    return true;
        return false;
    }

    public boolean isConnected(){
        return visited[t];
    }

    public Iterable<Integer> path(){

        ArrayList<Integer> res = new ArrayList<Integer>();
        if(!isConnected()) return res;

        int cur = t;
        while(cur != s){
            res.add(cur);
            cur = pre[cur];
        }
        res.add(s);

        Collections.reverse(res);
        return res;
    }

    public static void main(String[] args){

        Graph g = new Graph("g.txt");
        Path path = new Path(g, 0, 6);
        System.out.println("0 -> 6 : " + path.path());

        Path path2 = new Path(g, 0, 5);
        System.out.println("0 -> 5 : " + path2.path());

        Path path3 = new Path(g, 0, 1);
        System.out.println("0 -> 1 : " + path3.path());
        
        Path path4 = new Path(g, 0, 2);
        System.out.println("0 -> 2 : " + path4.path());
        
        System.out.println("\n————————————————————————————————————————");
        System.out.println("fbnq(8) = "+fbnq(8));
        System.out.println("fbnq(2) = "+fbnq(2));
        System.out.println("fbnq(47) = "+fbnq(47) +" [此时int溢出]");
        
        double s = System.nanoTime();
        double x = fbnq(700000);
        double e = System.nanoTime();
        System.out.println("fbnq() = "+x+" time="+(e-s)/1000000000);
    }
    
    //斐波那契数列
    private static double fbnq(long i) {
    	assert i > 0;
    	LinkedList<Long> arr = new LinkedList<>();
    	arr.add(1L);
    	arr.add(1L);
    	if( i < 3 ) return 1L;
    	
    	for(int j = 0; j < i-2; j++) {
    		arr.add(j+2, ( arr.get(j) + arr.get(j+1) ) );
    	}
    	
    	return arr.get(arr.size()-1);
    }
}
